﻿using System;
using System.Web;
using System.Configuration;

namespace Fuse8.ContentManagementFramework.Web.Caching
{
    public class CmsOutputCacheConfiguration : ConfigurationSection
    {        
        private string _cacheDirectoryLocation;
        private TimeSpan _fileRemovalDelay;
        private TimeSpan _capturingWaitTime;
        private CachedUrlsCollection _allowCachedUrls;
        private CachedUrlsCollection _denyCachedUrls;

        private HttpContextBase _currentContext = null;

        public virtual HttpContextBase CurrentContext
        {
            get
            {
                return _currentContext == null ?
                    new HttpContextWrapper(HttpContext.Current) :
                    _currentContext;
            }
            set
            {
                _currentContext = value;
            }
        }

        [ConfigurationProperty("cacheDirectoryLocation", DefaultValue = "~/cache_output", IsKey = false, IsRequired = false)]
        public virtual string CacheDirectoryLocation 
        {
            get
            {
                if (string.IsNullOrEmpty(_cacheDirectoryLocation))
                {
                    _cacheDirectoryLocation = CurrentContext.Server.MapPath(base["cacheDirectoryLocation"].ToString());
                }

                return _cacheDirectoryLocation;
            }
            set
            {
                _cacheDirectoryLocation = value;
                base["cacheDirectoryLocation"] = _cacheDirectoryLocation;
            }
        }

        [ConfigurationProperty("fileRemovalDelay", DefaultValue = "00:00:05", IsKey = false, IsRequired = false)]
        public virtual TimeSpan FileRemovalDelay 
        {
            get
            {
                if (_fileRemovalDelay == TimeSpan.MinValue)
                {
                    _fileRemovalDelay = (TimeSpan)base["fileRemovalDelay"];
                }

                return _fileRemovalDelay;
            }
            set 
            {
                _fileRemovalDelay = value;
                base["fileRemovalDelay"] = _fileRemovalDelay;
            }
        }

        [ConfigurationProperty("capturingWaitTime", DefaultValue = "00:00:10", IsKey = false, IsRequired = false)]
        public virtual TimeSpan CapturingWaitTime
        {
            get
            {
                if (_capturingWaitTime == TimeSpan.MinValue)
                {
                    _capturingWaitTime = (TimeSpan)base["capturingWaitTime"];
                }

                return _capturingWaitTime;
            }
            set
            {
                _capturingWaitTime = value;
                base["capturingWaitTime"] = _capturingWaitTime;
            }
        }

        [ConfigurationProperty("allowCachedUrls")]
        public CachedUrlsCollection AllowCachedUrls
        {
            get
            {
                if (_allowCachedUrls == null)
                {
                    _allowCachedUrls = base["allowCachedUrls"] as CachedUrlsCollection;
                }

                return _allowCachedUrls;
            }
        }

        [ConfigurationProperty("denyCachedUrls")]
        public CachedUrlsCollection DenyCachedUrls
        {
            get
            {
                if (_denyCachedUrls == null)
                {
                    _denyCachedUrls = base["denyCachedUrls"] as CachedUrlsCollection;
                }

                return _denyCachedUrls;
            }
        }
    }

    [ConfigurationCollectionAttribute(typeof(CachedUrlsElement))]
    public class CachedUrlsCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new CachedUrlsElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return (element as CachedUrlsElement).Path;
        }

        public void Add(CachedUrlsElement element)
        {
            this.BaseAdd(element);
        }

        public void Remove(string key)
        {
            this.BaseRemove(key);
        }

        public void Clear()
        {
            this.BaseClear();
        }
    }

    public class CachedUrlsElement : ConfigurationElement
    {
        [ConfigurationProperty("path", DefaultValue = "", IsKey = true, IsRequired = true)]
        public string Path
        {
            get
            {
                return base["path"].ToString();
            }
            set
            {
                base["path"] = value;
            }
        }

        [ConfigurationProperty("serveFromMemory", DefaultValue = false, IsKey = false, IsRequired = false)]
        public bool ServeFromMemory
        {
            get
            {
                return (bool)base["serveFromMemory"];
            }
            set
            {
                base["serveFromMemory"] = value;
            }
        }
    }
}
